/*
 * REFEventInterrupter.h
 *
 *  Created on: Jun 5, 2013
 *      Author: Lucifer
 */

#ifndef __EVENTINTERRUPTER_H__
#define __EVENTINTERRUPTER_H__

namespace BFX
{

class REFEventInterrupter;

#if defined(_WIN32) || defined(__CYGWIN__)

////////////////////////////////////////////////////////////////////////////////

/**
 * This class uses to interrupt the select function.
 */
class REFEventInterrupter : public REFObject
{
public:
	/**
	 * Initializes a new instance of BFX::REFEventInterrupter.
	 */
	REFEventInterrupter();

	/**
	 * Destroys the BFX::REFEventInterrupter instance.
	 */
	virtual ~REFEventInterrupter();

	/**
	 * Interrupt the select call.
	 * A single byte may be written to this to wake up the select which is waiting for the other end to become readable.
	 */
	void Interrupt();

	/**
	 * Reset the select interrupt.
	 * a single byte will be written on the other end of the connection and this descriptor will become readable.
	 *
	 * @return True if the call was interrupted.
	 */
	bool Reset();

	/**
	 * Gets the file descriptor uses to interrupt a select call.
	 * @return
	 */
	SOCKET GetFileDescriptor() const
	{
		return m_fdRecv;
	}

private:
	// Forbidden copy constructor and assignment operator.
	REFEventInterrupter(const REFEventInterrupter&);
	REFEventInterrupter& operator = (const REFEventInterrupter&);

private:
	SOCKET	m_fdRecv;
	SOCKET	m_fdSend;
};

#elif defined(BFX_IO_HAS_EVENTFD)

#else

class REFEventInterrupter
{
public:
	void Interrupt() {}
	bool Reset() { return false; }
	SOCKET GetFileDescriptor() const { return INVALID_SOCKET; }
};

#endif


} /* namespace BFX */
#endif /* __EVENTINTERRUPTER_H__ */
